package cn.brilliantfuture.commentry.servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.util.JSONUtils;
import cn.brilliantfuture.commentry.constants.OrderConstant;
import cn.brilliantfuture.commentry.entity.DataModels;
import cn.brilliantfuture.commentry.entity.Lockers;
import cn.brilliantfuture.commentry.entity.OrderInformation;
import cn.brilliantfuture.commentry.entity.OrderProductInfo;
import cn.brilliantfuture.commentry.entity.Purchaser;
import cn.brilliantfuture.commentry.entity.UserGroup;
import cn.brilliantfuture.commentry.exception.DuplicateSubmitException;
import cn.brilliantfuture.commentry.exception.InvokeFailureException;
import cn.brilliantfuture.commentry.exception.NullDataException;
import cn.brilliantfuture.commentry.exception.ParamErrorException;
import cn.brilliantfuture.commentry.order.OrderMessageLocal;
import cn.brilliantfuture.commentry.safe.VerifyMessageLocal;
import cn.brilliantfuture.commentry.user.UserMessageLocal;
import cn.brilliantfuture.commentry.util.CheckMatcher;
import cn.brilliantfuture.commentry.util.DateTimeHelper;

/**
 * Servlet implementation class OrderTransferServlet
 */
public class OrderTransferServlet extends AbstractHttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String appKey = request.getParameter("app_key");
		String appCode = request.getParameter("app_code");
		String version = request.getParameter("v");
		String timestamp = request.getParameter("timestamp");
		String format = request.getParameter("format");
		String orderInfo = request.getParameter("order_info");
		//String callback = request.getParameter("call");
		orderInfo = orderInfo.replace("\r\n", "");
		String result = work(appKey, appCode, version, timestamp, format, orderInfo);
		
		response.setContentType("application/json; charset=utf-8");
		response.setCharacterEncoding("utf-8");
		response.setHeader("Cache-Control", "no-cache");
		response.getWriter().print(result);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}
	
	private String work(String appKey, String appCode, String version, String timestamp, String format, String orderInfo){

		logger.info("Order transfer request data is : order_info -> " + orderInfo);

		JSONObject result = new JSONObject();

		try {
			
			validParam(appKey, appCode, version, timestamp, format);
			
			VerifyMessageLocal verifyMessageLocal = (VerifyMessageLocal) context.lookup("commentry-ear/VerifyMessageImpl/local");
			
			Integer groupId = verifyMessageLocal.validAppParam(appKey, appCode);
			
			Date currentDate = new Date();

			orderInfo = orderInfo.replace("\r\n", "");

			JSONObject obj = JSONObject.fromObject(orderInfo);
			OrderInformation orderInformation = new OrderInformation();
			Lockers lockers = new Lockers();
			DataModels dataModels = new DataModels();
			Purchaser purchaser = new Purchaser();
			UserGroup group = new UserGroup();

			List<OrderProductInfo> orderProductInfos = new ArrayList<OrderProductInfo>();

			logger.info("Order message - > " + obj.toString());
			logger.info("Protocol version : " + obj.getDouble("version"));

			JSONObject memnerInfo = obj.getJSONObject("receiver_info");
			
			UserMessageLocal userMessageLocal = (UserMessageLocal) context.lookup("commentry-ear/UserMessageImpl/local");
		
			group.setGroupId(groupId);
			orderInformation.setGroup(group);

			String nickName = memnerInfo.getString("nick_name");
			String phone = memnerInfo.getString("receiver_phone");
			String email = memnerInfo.getString("receiver_email");
			Integer language = memnerInfo.containsKey("language") ? JSONUtils.isNull(memnerInfo.get("language")) ? null : memnerInfo.getInt("language") : null;
			
			logger.info("NickName : " + nickName);
			logger.info("Phone : " + phone);
			logger.info("E-mail : " + email);
			
			if ((null == phone || "".equals(phone)) && (null == email || "".equals(email))){
				logger.error("Phone or emial not null!");
				throw new ParamErrorException();
			}

			// 验证手机号码及E-MAIL的合法性
			if (null != phone && !"".equals(phone)){
				if (!CheckMatcher.check(phone, CheckMatcher.REGEX_HANDSET_NUMBER)) {
					logger.error("Check phone fail!");
					throw new ParamErrorException();
				}
			}
			
			if (null != email && !"".equals(email)){
				if (!CheckMatcher.check(email, CheckMatcher.REGEX_EMAIL)){
					logger.error("Check email fail!");
					throw new ParamErrorException();
				}
			}

			Object[] memberInfo = null;

			// 不同协议版本处理绿色家递会员信息
			if (obj.getDouble("version") == 1.0D) {
				memberInfo = userMessageLocal.validMemberCode(memnerInfo.getString("receiver_id"));
			} else if (obj.getDouble("version") == 1.2D) {
				memberInfo = userMessageLocal.validMemberInfo(phone, email);
				if (null == memberInfo) {
					memberInfo = userMessageLocal.createNewMemberInfo(nickName, email, phone, language);
				}
			} else {
				throw new NullDataException();
			}

			if (null == memberInfo) {
				throw new InvokeFailureException();
			}

			// 组织订单信息
			purchaser.setPurchaserId((Integer) memberInfo[0]);
			orderInformation.setPurchaser(purchaser);
			orderInformation.setReceiveName(nickName);
			orderInformation.setReceivePhone(phone);
			orderInformation.setRecevieEmail(email);

			orderInformation.setNumber(groupId.intValue() + obj.getString("order_code"));

			lockers.setLockersId(obj.getInt("delivery_address"));
			orderInformation.setLockers(lockers);

			orderInformation.setStoreMode(obj.getInt("store_mode"));

			if (obj.getInt("store_scope") != 0) {
				dataModels.setDataModelId(obj.getInt("store_scope"));
				orderInformation.setDataModels(dataModels);
			}

			orderInformation.setPaymentMode(obj.getInt("payment_mode"));
			orderInformation.setTotalAmount(obj.getDouble("order_total_price"));

			Date beginTime = DateTimeHelper.strToDateTime(obj.getString("store_begin_time"), DateTimeHelper.DEFAULT_DATE_TIME_FORMAT);
			Date endTime = DateTimeHelper.strToDateTime(obj.getString("store_end_time"), DateTimeHelper.DEFAULT_DATE_TIME_FORMAT);

			if (null != beginTime)
				orderInformation.setDeliveryTime(beginTime);

			if (null != endTime)
				orderInformation.setDeliveryEndTime(endTime);

			orderInformation.setOrderRemark(obj.getString("order_remark"));

			orderInformation.setInsertTime(currentDate);
			orderInformation.setEffective(true);
			orderInformation.setOrderSource(OrderConstant.ORDER_SOURCE_ONLINE_MALL);
			orderInformation.setTransactions(OrderConstant.WAIT_HANDLE);
			orderInformation.setOrderType(OrderConstant.DELIVERY_ORDER_TYPE);
			orderInformation.setDeleted(false);

			JSONArray productInfos = obj.getJSONArray("product_infos");

			// 获取商品信息
			for (int i = 0; i < productInfos.size(); i++) {
				JSONObject productInfo = productInfos.getJSONObject(i);

				OrderProductInfo orderProductInfo = new OrderProductInfo();
				orderProductInfo.setProductInfoId(productInfo.getInt("product_id"));
				orderProductInfo.setProductName(productInfo.getString("product_name"));
				orderProductInfo.setUnit(productInfo.getString("product_unit"));
				orderProductInfo.setPrice(productInfo.getDouble("price"));
				orderProductInfo.setAmount(productInfo.getInt("product_num"));
				orderProductInfo.setTotalPrice(productInfo.getDouble("total_price"));
				orderProductInfo.setInsertTime(currentDate);
				orderProductInfo.setDeleted(false);

				orderProductInfos.add(orderProductInfo);
			}
			
			OrderMessageLocal orderMessageLocal = (OrderMessageLocal) context.lookup("commentry-ear/OrderMessageImpl/local");
			
			// 确认是否为重复提交配送单
			if (!orderMessageLocal.isExistForOrder(orderInformation.getNumber())) {
				throw new DuplicateSubmitException();
			}

			// 保存配送单及商品信息
			if (orderMessageLocal.saveOrderInfo(orderInformation, orderProductInfos)) {
				result.accumulate("invoke_result", INVOKE_SUCCESS);
			} else {
				throw new InvokeFailureException();
			}
			
		} catch (ParamErrorException e) {
			result.accumulate("invoke_result", PARAM_ERROR);
		} catch (NamingException e) {
			result.accumulate("invoke_result", INVOKE_FAILURE);
		} catch (NullDataException e) {
			result.accumulate("invoke_result", NULL_DATA);
		} catch (InvokeFailureException e) {
			result.accumulate("invoke_result", INVOKE_FAILURE);
		} catch (DuplicateSubmitException e) {
			result.accumulate("invoke_result", DUPLICATE_SUBMIT);
		}
		
		logger.info("Return result -> " + result.toString());
		
		return result.toString();
	}

}
